package com.solo.system.service.impl;

import cn.hutool.core.util.NumberUtil;
import com.solo.common.core.base.service.impl.BasicServiceImpl;
import com.solo.common.core.utils.StringUtils;
import com.solo.system.api.consts.SystemCacheKey;
import com.solo.system.api.entity.SysRole;
import com.solo.system.mapper.SysRoleDeptMapper;
import com.solo.system.mapper.SysRoleMapper;
import com.solo.system.mapper.SysRoleMenuMapper;
import com.solo.system.mapper.SysUserRoleMapper;
import com.solo.system.model.role.SysRoleConvert;
import com.solo.system.model.role.resp.RoleGetResp;
import com.solo.system.service.SysRoleService;
import lombok.AllArgsConstructor;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collection;
import java.util.Objects;

import static com.solo.common.core.utils.ServiceExceptionUtil.exception;
import static com.solo.system.api.consts.SystemCode.*;

/**
 * 系统角色Service实现类
 * @author 十一
 * @since 2023/09/22 17:29
 * 人生若只如初见，何事秋风悲画扇
 **/
@Service
@AllArgsConstructor
public class SysRoleServiceImpl extends BasicServiceImpl<SysRoleMapper, SysRole> implements SysRoleService {

    private final SysRoleMapper sysRoleMapper;
    private final SysUserRoleMapper sysUserRoleMapper;
    private final SysRoleDeptMapper sysRoleDeptMapper;
    private final SysRoleMenuMapper sysRoleMenuMapper;
    
    @Override
    @CachePut(value = SystemCacheKey.ROLE, key = "#entity.roleId")
    public boolean create(SysRole entity) {
        // 验证角色名称是否唯一
        validateNameUnique(entity.getName(), null);
        // 验证角色编码是否唯一
        validateCodeUnique(entity.getCode(), null);
        // 保存角色
        return save(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean delete(Collection<Long> roleIds) {
        // 删除用户角色关联
        sysUserRoleMapper.deleteByRoleIds(roleIds);
        // 删除角色菜单关联
        sysRoleMenuMapper.deleteByRoleIds(roleIds);
        // 删除角色部门关联
        sysRoleDeptMapper.deleteByRoleIds(roleIds);
        // 删除角色信息
        return removeByIds(roleIds);
    }

    @Override
    @CachePut(value = SystemCacheKey.ROLE, key = "#entity.roleId")
    public boolean update(SysRole entity) {
        Long roleId = entity.getRoleId();
        // 验证角色是否存在
        validateExists(roleId);
        // 验证角色名称是否唯一
        validateNameUnique(entity.getName(), roleId);
        // 验证角色编码是否唯一
        validateCodeUnique(entity.getCode(), roleId);
        // 更新角色
        return updateById(entity);
    }

    @Override
    @Cacheable(cacheNames = SystemCacheKey.ROLE, key = "#roleId", unless = "#result == null")
    public RoleGetResp get(Long roleId) {
        return SysRoleConvert.INSTANCE.convertGet(mapper.selectOneById(roleId));
    }

    /**
     * 验证角色是否存在
     * @param roleId 角色id
     */
    void validateExists(Long roleId) {
        if (roleId == null) {
            return;
        }
        SysRole entity = mapper.selectOneById(roleId);
        if (entity == null) {
            throw exception(ROLE_NOT_EXISTS);
        }
    }

    /**
     * 验证角色名称是否唯一
     * @param name 名称
     * @param roleId 角色ID
     */
    void validateNameUnique(String name, Long roleId) {
        if (StringUtils.isEmpty(name)) {
            return;
        }
        SysRole role = sysRoleMapper.selectByName(name);
        if (!Objects.isNull(role) && !NumberUtil.equals(role.getRoleId(), roleId)) {
            throw exception(ROLE_NAME_EXISTS, name);
        }
    }

    /**
     * 验证角色代码是否唯一
     * @param code 角色代码
     * @param roleId 角色id
     */
    void validateCodeUnique(String code, Long roleId) {
        if (StringUtils.isEmpty(code)) {
            return;
        }
        SysRole role = sysRoleMapper.selectByCode(code);
        if (!Objects.isNull(role) && !NumberUtil.equals(role.getRoleId(), roleId)) {
            throw exception(ROLE_CODE_EXISTS, code);
        }
    }

}
